feat: pass anon_id from dapp to wallet in SDKConnectV2 connection metadata for cross-side analytics correlation#28470
feat: pass anon_id from dapp to wallet in SDKConnectV2 connection metadata for cross-side analytics correlation#28470ffmcgee725 wants to merge 9 commits intomainfrom
Conversation
…adata for cross-side analytics correlation
app/core/SDKConnectV2/adapters/host-application-adapter.test.ts
Outdated
Show resolved
Hide resolved
| chain_id_list: chainIds, | ||
| referrer: channelIdOrHostname, | ||
| ...getApiAnalyticsProperties(isMultichainRequest), | ||
| ...(anonId ? { anon_id: anonId } : {}), |
There was a problem hiding this comment.
I believe in all of these cases it should be added as a sensitive property as it is done in all of the SDKv1 instances?
.addSensitiveProperties({ anon_id: anonId })
app/components/Views/MultichainAccounts/MultichainAccountConnect/MultichainAccountConnect.tsx
Outdated
Show resolved
Hide resolved
| ...getApiAnalyticsProperties(isMultichainRequest), | ||
| }); | ||
| if (anonId) { | ||
| eventBuilder.addSensitiveProperties({ anon_id: anonId }); |
There was a problem hiding this comment.
is the id is already anonimized, is it still sensitive? If we trying to link mobile analytics identities to their dapp side identities, i'm not sure marking the property as sensitive would allow for that. If we only care about these specific events, then it should be fine
There was a problem hiding this comment.
We need an answer from @adamceresko to proceed here.
Slack Thread: https://consensys.slack.com/archives/C097JHB70J0/p1775682964092239?thread_ts=1775681064.627209&cid=C097JHB70J0
Jira Ticket Tracking this decision: https://consensyssoftware.atlassian.net/browse/WAPI-1402?atlOrigin=eyJpIjoiOGIzN2EwOTk4MDM2NGVjOGI1ODBiZDQzY2FkYWExZmYiLCJwIjoiamlyYS1zbGFjay1pbnQifQ
anon_id is a dapp-generated UUID for cross-side analytics correlation, not a sensitive identifier. Marking it sensitive triggered the anonymous event split (zeroed userId), which prevented linking dapp sessions to wallet user activity. Per team consensus (Jiexi, Adam, Alex), this is not actually sensitive data so it belongs in regular properties.
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
| accountType = getAddressAccountType(selectedCaipAccountIds[0]); | ||
| } catch { | ||
| accountType = 'unknown'; | ||
| } |
There was a problem hiding this comment.
Unrelated behavior change bundled without test coverage
Medium Severity
getAddressAccountType receives selectedCaipAccountIds[0], which is a CAIP account ID (e.g. a Solana eip155:… or solana:… format). Internally, the function parses the address then calls toFormattedAddress, which uses toChecksumAddress — an EVM-only operation that will throw for non-EVM chain addresses. While the try/catch gracefully defaults to 'unknown', the previous hard-coded 'multichain' value was semantically more accurate for this multichain flow. This behavior change (from 'multichain' to a per-address keyring lookup) is unrelated to the anon_id plumbing described in the PR and silently degrades the account_type analytics property to 'unknown' for all non-EVM account selections.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 3771262. Configure here.
The property was an opaque dapp-generated UUID used for cross-side analytics correlation — "remote_session_id" better describes its purpose. Updated the Metadata type, connection-request validation, host-application adapter mapping, event properties on Connect Request events, and all related tests. Aligns with the segment-schema definitions which already use remote_session_id.
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: The PR introduces analytics telemetry enhancements to SDK V2 connection flows:
Tags selected:
Performance tests: Not selected - changes are purely analytics/telemetry additions (optional spread of Performance Test Selection: |
…rties Aligns with the decision in PR #28470 — remote_session_id is a dapp-generated UUID for cross-side analytics correlation, not sensitive data. Keeping it in sensitiveProperties triggered the anonymous event split which prevented linking dapp sessions to wallet user activity.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ec0f6c9. Configure here.
| !isUUID(metadata.analytics.remote_session_id) | ||
| ) { | ||
| delete (metadata as unknown as Record<string, unknown>).analytics; | ||
| } |
There was a problem hiding this comment.
Type guard mutates its input argument silently
Low Severity
The isConnectionRequest type guard mutates its input by deleting metadata.analytics when malformed. Type guards are conventionally pure predicate functions — callers don't expect them to have side effects on the checked object. Since data is passed by reference, the deletion silently alters the caller's object. Extracting the sanitization into a separate step (e.g., a sanitizeConnectionRequest function called after the guard) would make the mutation explicit and keep the type guard free of side effects.
Reviewed by Cursor Bugbot for commit ec0f6c9. Configure here.
|
|
✅ E2E Fixture Validation — Schema is up to date |




Description
Accepts and plumbs the dapp-provided
anon_idthrough V2 (MWP) connections so wallet-side analytics events can be correlated with dapp-side events — matching the cross-side correlation that SDK v1 already provides.analytics?: { anon_id: string }to theMetadatatypemetadata.analytics.anon_idin theisConnectionRequesttype guardanon_idintooriginatorInfo.anonIdviaHostApplicationAdapter.syncConnectionList()anon_idas a property on existingCONNECT_REQUEST_STARTED,CONNECT_REQUEST_COMPLETED, andCONNECT_REQUEST_CANCELLEDanalytics events (only when present, for V2 connections)Related
Changelog
CHANGELOG entry: null
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
After
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Touches SDKConnectV2 connection-request validation and connection/session plumbing, which could affect remote connection establishment if mishandled. Runtime impact is mostly telemetry-only (optional field, stripped when malformed) but analytics event payloads change across connect flows.
Overview
Adds optional
metadata.analytics.remote_session_idto SDKConnectV2 connection requests, validating it as a UUID and stripping malformed analytics payloads instead of rejecting the connection.Plumbs the value into
originatorInfo.anonIdviaHostApplicationAdapter.syncConnectionList()and conditionally attaches it asremote_session_idonCONNECT_REQUEST_STARTED,CONNECT_REQUEST_CANCELLED, andCONNECT_REQUEST_COMPLETEDevents inPermissionApproval,AccountConnect, andMultichainAccountConnect.Improves multichain connect analytics by deriving
account_typeviagetAddressAccountType(fallbackunknown) instead of the previous hardcoded value, and extends tests to cover the new analytics field and adapter behavior.Reviewed by Cursor Bugbot for commit ec0f6c9. Bugbot is set up for automated code reviews on this repo. Configure here.